package com.yx.frame.builder.code;

import java.util.List;
import com.yx.frame.builder.xml.MethodContentXml;
import com.yx.frame.builder.xml.MethodParmXml;
import com.yx.frame.builder.xml.MethodXml;
import com.yx.frame.builder.xml.QueryMethodContentXml;
import com.yx.frame.builder.xml.QueryMethodContentXml.QuerySql;
import com.yx.frame.builder.xml.UpdateMethodContentXml;
import com.yx.frame.service.Action;

public abstract class MethodBuilder {

	String className = null;
	String shortClassName = null;
	MethodXml method;

	public MethodBuilder(String className, String shortClassName,
			MethodXml method) throws Exception {
		this.className = className;
		this.shortClassName = shortClassName;
		this.method = method;
		if (method.getName() == null || "".equals(method.getName())) {
			throw new Exception("方法名不能为空");
		}
		if (!"query".equals(method.getType())
				&& !"update".equals(method.getType())
				&& !"java".equals(method.getType())) {
			throw new Exception("方法" + method.getName()
					+ "只支持query/update/java类型");
		}
	}

	public String getClassName() {
		return className;
	}

	public String getShortClassName() {
		return shortClassName;
	}

	public MethodXml getMethod() {
		return method;
	}
	public StringBuffer[] getIosClientCode( String jsControlName) throws Exception {
		String javaParmsStr = "";		
		List<MethodParmXml> methodParms=getMethod().getMethodParms();
		for (int i = 0; i < methodParms.size(); i++) {
			MethodParmXml methodParmXml = methodParms.get(i);			
			String parmType = "(NSString*)";
			if (methodParmXml.isMutilistType()) {
				parmType = "(NSArray *)";
			}
			if(i==0){
				javaParmsStr = javaParmsStr +":"+ parmType + methodParmXml.getName() + " ";
			}else{
				javaParmsStr = javaParmsStr +methodParmXml.getName()+":"+ parmType + methodParmXml.getName() + " ";
			}
		}
		
		if("query".equals(getMethod().getType())&&"true".equals(getMethod().getPagination())){
			if(!"".equals(javaParmsStr)){
				javaParmsStr = javaParmsStr + "PageIndex";
			}
			javaParmsStr = javaParmsStr + ":(NSInteger)pageIndex PageSize:(NSInteger)pageSize ";
		}
		MethodContentXml methodContentXml=getMethod().getMethodContentXml();
		if(methodContentXml instanceof UpdateMethodContentXml){
			if("true".equals(((UpdateMethodContentXml)methodContentXml).getUserDefineDatasource())){
				if(!"".equals(javaParmsStr)){
					javaParmsStr = javaParmsStr + "DatasourceOf"+this.getMethod().getName();
				}
				javaParmsStr = javaParmsStr + ":(NSString*)DatasourceOf"+ this.getMethod().getName()+ " ";
			}			
		}else if(methodContentXml instanceof QueryMethodContentXml){
			QueryMethodContentXml queryMethodContentXml=(QueryMethodContentXml)methodContentXml;
			List<String> queryUserDefineDatasource=queryMethodContentXml.getUserDefineDatasource();
			for(int i=0;i<queryUserDefineDatasource.size();i++){
				if(!"".equals(javaParmsStr)){
					javaParmsStr = javaParmsStr + queryUserDefineDatasource.get(i);
				}
				javaParmsStr = javaParmsStr + ":(NSArray *)"+ queryUserDefineDatasource.get(i)+ " ";
			}			
		}
		if (javaParmsStr.endsWith(" "))
			javaParmsStr = javaParmsStr.substring(0, javaParmsStr.length() - 1);
		StringBuffer code = new StringBuffer();
		StringBuffer headCode = new StringBuffer();
		code.append("/////////////////////////////////////////////////////////////////////\r\n");
		code.append("//编号：" + this.getMethod().getId()+ " 说明：" + this.getMethod().getComment()+ "\r\n");
		code.append("//作者：" + this.getMethod().getAuthor() + " 日期：" + this.getMethod().getDate() + "\r\n");
		code.append("/////////////////////////////////////////////////////////////////////\r\n");
		headCode.append("- (NSDictionary*) " + this.getMethod().getName()+"_"+this.getMethod().getId() + javaParmsStr + ";\r\n");
		code.append("- (NSDictionary*) " + this.getMethod().getName()+"_"+this.getMethod().getId() + javaParmsStr + " {\r\n");
		code.append("	NSMutableDictionary *dicRequest = [[NSMutableDictionary alloc]initWithCapacity:1];\r\n");		
        for (int i = 0; i < methodParms.size(); i++) {
			MethodParmXml methodParmXml = methodParms.get(i);
			code.append("	[dicRequest setObject:"+methodParmXml.getName()+" forKey:@\""+methodParmXml.getName()+"\"];\r\n");			
		}
		if("query".equals(getMethod().getType())&&"true".equals(getMethod().getPagination())){
			code.append("	NSNumber *PageIndexNumber = [NSNumber numberWithInteger:pageIndex];\r\n");
			code.append("	NSNumber *PageSizeNumber = [NSNumber numberWithInteger:pageSize];\r\n");
			code.append("	[dicRequest setObject:PageIndexNumber forKey:@\"PageIndex\"];\r\n");
			code.append("	[dicRequest setObject:PageSizeNumber forKey:@\"PageSize\"];\r\n");			
		}
		if(methodContentXml instanceof UpdateMethodContentXml){
			if("true".equals(((UpdateMethodContentXml)methodContentXml).getUserDefineDatasource())){
				code.append("	[dicRequest setObject:DatasourceOf"+this.getMethod().getName()+" forKey:@\"DatasourceOf"+this.getMethod().getName()+"\"];\r\n");				
			}			
		}else if(methodContentXml instanceof QueryMethodContentXml){
			QueryMethodContentXml queryMethodContentXml=(QueryMethodContentXml)methodContentXml;
			List<String> queryUserDefineDatasource=queryMethodContentXml.getUserDefineDatasource();
			for(int i=0;i<queryUserDefineDatasource.size();i++){
				code.append("	[dicRequest setObject:"+queryUserDefineDatasource.get(i)+" forKey:@\""+queryUserDefineDatasource.get(i)+"\"];\r\n");
			}			
		}
		code.append("	return [self post:"+getMethod().getId()+" asyncService:"+getMethod().getAsyncService()+" Data:dicRequest];\r\n");
		code.append("}\r\n");
		code.append("\r\n");
		StringBuffer[] returnSb=new StringBuffer[2];
		returnSb[0]=headCode;
		returnSb[1]=code;
		return returnSb;

	}

	public StringBuffer getJavaClientCode() throws Exception {
		String javaParmsStr = "";		
		List<MethodParmXml> methodParms=getMethod().getMethodParms();
		for (int i = 0; i < methodParms.size(); i++) {
			MethodParmXml methodParmXml = methodParms.get(i);			
			String parmType = "String";
			if (methodParmXml.isMutilistType()) {
				parmType = "JSONArray";
			}
			javaParmsStr = javaParmsStr + parmType + " "+ methodParmXml.getName() + ",";			
		}
		
		if("query".equals(getMethod().getType())&&"true".equals(getMethod().getPagination())){
			javaParmsStr = javaParmsStr + "  int pageIndex, int pageSize,";
		}
		MethodContentXml methodContentXml=getMethod().getMethodContentXml();
		if(methodContentXml instanceof UpdateMethodContentXml){
			if("true".equals(((UpdateMethodContentXml)methodContentXml).getUserDefineDatasource())){
				javaParmsStr = javaParmsStr + "String DatasourceOf"+ this.getMethod().getName()+ ",";
			}			
		}else if(methodContentXml instanceof QueryMethodContentXml){
			QueryMethodContentXml queryMethodContentXml=(QueryMethodContentXml)methodContentXml;
			List<String> queryUserDefineDatasource=queryMethodContentXml.getUserDefineDatasource();
			for(int i=0;i<queryUserDefineDatasource.size();i++){
				javaParmsStr = javaParmsStr + "JSONArray "+ queryUserDefineDatasource.get(i)+ ",";
			}			
		}
		if (javaParmsStr.endsWith(","))
			javaParmsStr = javaParmsStr.substring(0, javaParmsStr.length() - 1);
		MethodClientResultBuilder methodClientResultBuilder=new MethodClientResultBuilder(this.getMethod());
		StringBuffer code = new StringBuffer();
		code.append("/////////////////////////////////////////////////////////////////////\r\n");
		code.append("//编号：" + this.getMethod().getId()+ " 说明：" + this.getMethod().getComment()+ "\r\n");
		code.append("//作者：" + this.getMethod().getAuthor() + " 日期：" + this.getMethod().getDate() + "\r\n");
		code.append("/////////////////////////////////////////////////////////////////////\r\n");
		if("query".equals(getMethod().getType())){
			List<QuerySql> querySqlList = ((QueryMethodContentXml) getMethod().getMethodContentXml()).getTransaction();
			code.append("	public class QueryResult$"+getMethod().getId()+" {\r\n");
			code.append("		private QueryResult$"+getMethod().getId()+"(JSONObject data)throws Exception {\r\n");
			for(int i=0;i<querySqlList.size();i++){
				QuerySql querySql=querySqlList.get(i);
				String name=querySql.getName();
				code.append("			JSONArray "+name+"List=data.getJSONArray(\""+name+"\");\r\n");
				code.append("			for(int i=0;i<"+name+"List.length();i++){\r\n");
				code.append("				JSONObject row="+name+"List.getJSONObject(i);"+name+" rowObj=new "+name+"();\r\n");
				code.append("				");
				String[] cols=querySql.getSqlColumsArray();
				for(int j=0;j<cols.length;j++){
					code.append("rowObj."+cols[j]+"=row.getString(\""+cols[j]+"\");");
				}
				code.append(""+name+".add(rowObj);\r\n");
				code.append("			}\r\n");
			}
			code.append("		}\r\n");
			for(int i=0;i<querySqlList.size();i++){
				QuerySql querySql=querySqlList.get(i);
				String name=querySql.getName();
				code.append("		private List<"+name+"> "+name+"=new ArrayList<"+name+">();public List<"+name+"> get"+name+"(){return "+name+";}\r\n");
				code.append("		public class "+name+" {public String "+querySql.getSqlColums()+";}\r\n");
			}
			code.append("	}\r\n");
		}
		code.append("	public static final "+methodClientResultBuilder.getMethodClientResultName()+" " + this.getMethod().getName()+"_"+this.getMethod().getId() + "("+ javaParmsStr + ")  throws Exception {\r\n");
		code.append("		JSONObject jRequest = new JSONObject();\r\n");
		for (int i = 0; i < methodParms.size(); i++) {
			MethodParmXml methodParmXml = methodParms.get(i);
			code.append("		jRequest.put(\""+methodParmXml.getName()+"\","+methodParmXml.getName()+");\r\n");
		}
		if("query".equals(getMethod().getType())&&"true".equals(getMethod().getPagination())){
			code.append("		jRequest.put(\"PageIndex\",String.valueOf(pageIndex));\r\n");
			code.append("		jRequest.put(\"PageSize\",String.valueOf(pageSize));\r\n");
		}
		if(methodContentXml instanceof UpdateMethodContentXml){
			if("true".equals(((UpdateMethodContentXml)methodContentXml).getUserDefineDatasource())){
				code.append("		jRequest.put(\"DatasourceOf"+ this.getMethod().getName()+"\",DatasourceOf"+this.getMethod().getName()+");\r\n");
			}			
			code.append("		return getUpdateResult(post("+getMethod().getId()+","+getMethod().getAsyncService()+",jRequest));\r\n");
		}else if(methodContentXml instanceof QueryMethodContentXml){
			QueryMethodContentXml queryMethodContentXml=(QueryMethodContentXml)methodContentXml;
			List<String> queryUserDefineDatasource=queryMethodContentXml.getUserDefineDatasource();
			for(int i=0;i<queryUserDefineDatasource.size();i++){
				code.append("		jRequest.put(\""+queryUserDefineDatasource.get(i)+"\","+queryUserDefineDatasource.get(i)+");\r\n");
			}
			code.append("		return _instence.new  "+methodClientResultBuilder.getMethodClientResultName()+"(post("+getMethod().getId()+","+getMethod().getAsyncService()+",jRequest));\r\n");
		}else{
			code.append("		return post("+getMethod().getId()+","+getMethod().getAsyncService()+",jRequest);\r\n");
		}
		code.append("	}\r\n");
		code.append("\r\n");
		return code;
	}

	public abstract StringBuffer getJavaCode() throws Exception;

	public abstract StringBuffer[] getJsWebCode(String jsControlName) throws Exception;

	public Action getActionsDefination() throws Exception {
		Action action = new Action(method.getId(),
				method.getName(), getClassName(), method.getName(),
				method.getComment());
		return action;
	}
	public static String splitParms(String parmStr,String returnMask){
		try{
			String[] parms=parmStr.split(",");
			String returnParmsStr="";
			for(int i=0;i<parms.length;i++){
				if(i!=0&&i%5==0){
					returnParmsStr=returnParmsStr+","+returnMask+parms[i];	
				}else{
					returnParmsStr=returnParmsStr+","+parms[i];	
				}
			}
			if(returnParmsStr.length()>0)returnParmsStr=returnParmsStr.substring(1);
			if(parmStr.endsWith(","))returnParmsStr=returnParmsStr+",";
			return returnParmsStr;
		}catch(Exception e){			
			return parmStr;
		}
	}	
	public static String splitParmsHtml(String parmStr){
		return splitParms(parmStr,"<br>&nbsp;&nbsp;&nbsp;&nbsp;");
	}
}
